/**
 * Calculation Handler
 * Takes in Initial Position, Target Position, Initial Value, and Category
 * Gives the calculated conversion
 */

package umuc.cmsc495.mach2;

import umuc.cmsc495.mach2.unit.MetricUnit;
import umuc.cmsc495.mach2.unit.TemperatureUnit;
import umuc.cmsc495.mach2.unit.english.EnglishAreaUnit;
import umuc.cmsc495.mach2.unit.english.EnglishDryCapacityUnit;
import umuc.cmsc495.mach2.unit.english.EnglishLengthUnit;
import umuc.cmsc495.mach2.unit.english.EnglishMassUnit;
import umuc.cmsc495.mach2.unit.english.EnglishVolumeUnit;
import umuc.cmsc495.mach2.unit.english.EnglishWetCapacityUnit;

/**
 * @author Michael Swann
 */
public class CalculationHandler {

    // Length Positions
    private final static int ENGLISH_LENGTH_START       = 0;
    private final static int ENGLISH_LENGTH_END	 	= 3;
    private final static int METRIC_LENGTH_START	= 4;
    private final static int METRIC_LENGTH_END	  	= 10;
    // Area Positions
    private final static int ENGLISH_AREA_START	 	= 0;
    private final static int ENGLISH_AREA_END	   	= 4;
    private final static int METRIC_AREA_START	  	= 5;
    private final static int METRIC_AREA_END	    	= 11;
    // Volume Positions
    private final static int ENGLISH_VOLUME_START       = 0;
    private final static int ENGLISH_VOLUME_END	 	= 2;
    private final static int METRIC_VOLUME_START	= 3;
    private final static int METRIC_VOLUME_END	  	= 9;
    // Dry Capacity Positions
    private final static int ENGLISH_DRY_CAPACITY_START = 0;
    private final static int ENGLISH_DRY_CAPACITY_END   = 3;
    private final static int METRIC_DRY_CAPACITY_START  = 4;
    private final static int METRIC_DRY_CAPACITY_END    = 10;
    // Wet Capacity Positions
    private final static int ENGLISH_WET_CAPACITY_START = 0;
    private final static int ENGLISH_WET_CAPACITY_END   = 3;
    private final static int METRIC_WET_CAPACITY_START  = 4;
    private final static int METRIC_WET_CAPACITY_END    = 10;
    // Mass Positions
    private final static int ENGLISH_MASS_START	 	= 0;
    private final static int ENGLISH_MASS_END	  	= 4;
    private final static int METRIC_MASS_START	  	= 5;
    private final static int METRIC_MASS_END	    	= 11;

    public static double parseAndCalculate(int categoryPos, int initTypePos, int targTypePos, double initValue) {

	EnglishLengthUnit[] englishLengthUnits = EnglishLengthUnit.values();
	EnglishAreaUnit[] englishAreaUnits = EnglishAreaUnit.values();
	EnglishVolumeUnit[] englishVolumeUnits = EnglishVolumeUnit.values();
	EnglishDryCapacityUnit[] englishDryCapacityUnits = EnglishDryCapacityUnit.values();
	EnglishWetCapacityUnit[] englishWetCapacityUnits = EnglishWetCapacityUnit.values();
	EnglishMassUnit[] englishMassUnits = EnglishMassUnit.values();
	MetricUnit[] metricUnits = MetricUnit.values();
	TemperatureUnit[] temperatureUnits = TemperatureUnit.values();

	double result = 0.0;

	switch (categoryPos) {
	case 0: // Length
	{
	    if ((targTypePos >= ENGLISH_LENGTH_START) && (targTypePos <= ENGLISH_LENGTH_END)) {

		if ((initTypePos >= ENGLISH_LENGTH_START) && (initTypePos <= ENGLISH_LENGTH_END)) {

		    result = englishLengthUnits[targTypePos].convert(initValue,
			    englishLengthUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_LENGTH_START && (initTypePos <= METRIC_LENGTH_END))) {

		    double inches = metricUnits[initTypePos - METRIC_LENGTH_START]
			    .toEnglishInches(initValue);
		    result = englishLengthUnits[targTypePos].convert(inches,
			    EnglishLengthUnit.INCHES);

		}

	    } else if ((targTypePos >= METRIC_LENGTH_START && (targTypePos <= METRIC_LENGTH_END))) {

		if ((initTypePos >= ENGLISH_LENGTH_START) && (initTypePos <= ENGLISH_LENGTH_END)) {

		    double meters = englishLengthUnits[initTypePos]
			    .toMeters(initValue);
		    result = metricUnits[targTypePos - METRIC_LENGTH_START].convert(meters,
			    MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_LENGTH_START && (initTypePos <= METRIC_LENGTH_END))) {

		    result = metricUnits[targTypePos - METRIC_LENGTH_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_LENGTH_START]);

		}

	    }
	    break;
	}
	case 1: // Area
	{
	    if ((targTypePos >= ENGLISH_AREA_START) && (targTypePos <= ENGLISH_AREA_END)) {
		
		if ((initTypePos >= ENGLISH_AREA_START) && (initTypePos <= ENGLISH_AREA_END)) {

		    result = englishAreaUnits[targTypePos].convert(initValue,
			    englishAreaUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_AREA_START && (initTypePos <= METRIC_AREA_END))) {

		    double squareInches = metricUnits[initTypePos - METRIC_AREA_START]
			    .toEnglishSquareInches(initValue);
		    result = englishAreaUnits[targTypePos].convert(squareInches,
			    EnglishAreaUnit.SQUAREINCHES);

		}
	    } else if ((targTypePos >= METRIC_AREA_START && (targTypePos <= METRIC_AREA_END))) {
		
		if ((initTypePos >= ENGLISH_AREA_START) && (initTypePos <= ENGLISH_AREA_END)) {

		    double squareMeters = englishAreaUnits[initTypePos]
			    .toSquareMeters(initValue);
		    result = metricUnits[targTypePos - METRIC_AREA_START].convert(squareMeters,
			    MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_AREA_START && (initTypePos <= METRIC_AREA_END))) {

		    result = metricUnits[targTypePos - METRIC_AREA_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_AREA_START]);

		}
	    }
	    break;
	}
	case 2: // Volume
	{
	    if ((targTypePos >= ENGLISH_VOLUME_START) && (targTypePos <= ENGLISH_VOLUME_END)) {

		if ((initTypePos >= ENGLISH_VOLUME_START) && (initTypePos <= ENGLISH_VOLUME_END)) {

		    result = englishVolumeUnits[targTypePos].convert(initValue,
			    englishVolumeUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_VOLUME_START && (initTypePos <= METRIC_VOLUME_END))) {

		    double cubicInches = metricUnits[initTypePos - METRIC_VOLUME_START]
			    .toEnglishCubicInches(initValue);
		    result = englishVolumeUnits[targTypePos].convert(cubicInches,
			    EnglishVolumeUnit.CUBICINCHES);

		}

	    } else if ((targTypePos >= METRIC_VOLUME_START && (targTypePos <= METRIC_VOLUME_END))) {

		if ((initTypePos >= ENGLISH_VOLUME_START) && (initTypePos <= ENGLISH_VOLUME_END)) {

		    double cubicMeters = englishVolumeUnits[initTypePos]
			    .toCubicMeters(initValue);
		    result = metricUnits[targTypePos - METRIC_VOLUME_START].convert(cubicMeters,
			    MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_VOLUME_START && (initTypePos <= METRIC_VOLUME_END))) {

		    result = metricUnits[targTypePos - METRIC_VOLUME_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_VOLUME_START]);

		}
	    }
	    break;
	}
	case 3: // Dry Capacity
	{
	    if ((targTypePos >= ENGLISH_DRY_CAPACITY_START) && (targTypePos <= ENGLISH_DRY_CAPACITY_END)) {

		if ((initTypePos >= ENGLISH_DRY_CAPACITY_START) && (initTypePos <= ENGLISH_DRY_CAPACITY_END)) {

		    result = englishDryCapacityUnits[targTypePos].convert(initValue,
			    englishDryCapacityUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_DRY_CAPACITY_START && (initTypePos <= METRIC_DRY_CAPACITY_END))) {

		    double quarts = metricUnits[initTypePos - METRIC_DRY_CAPACITY_START]
			    .toEnglishDryQuarts(initValue);
		    result = englishDryCapacityUnits[targTypePos].convert(quarts,
			    EnglishDryCapacityUnit.QUARTS);

		}
	    } else if ((targTypePos >= METRIC_DRY_CAPACITY_START && (targTypePos <= METRIC_DRY_CAPACITY_END))) {

		if ((initTypePos >= ENGLISH_DRY_CAPACITY_START) && (initTypePos <= ENGLISH_DRY_CAPACITY_END)) {

		    double liters = englishDryCapacityUnits[initTypePos]
			    .toLiters(initValue);
		    result = metricUnits[targTypePos - METRIC_DRY_CAPACITY_START].convert(liters,
			    MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_DRY_CAPACITY_START && (initTypePos <= METRIC_DRY_CAPACITY_END))) {

		    result = metricUnits[targTypePos - METRIC_DRY_CAPACITY_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_DRY_CAPACITY_START]);

		}
	    }
	    break;
	}
	case 4: // Wet Capacity
	{
	    if ((targTypePos >= ENGLISH_WET_CAPACITY_START) && (targTypePos <= ENGLISH_WET_CAPACITY_END)) {

		if ((initTypePos >= ENGLISH_WET_CAPACITY_START) && (initTypePos <= ENGLISH_WET_CAPACITY_END)) {

		    result = englishWetCapacityUnits[targTypePos].convert(initValue,
			    englishWetCapacityUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_WET_CAPACITY_START && (initTypePos <= METRIC_WET_CAPACITY_END))) {

		    double quarts = metricUnits[initTypePos - METRIC_WET_CAPACITY_START]
			    .toEnglishWetQuarts(initValue);
		    result = englishWetCapacityUnits[targTypePos].convert(quarts,
			    EnglishWetCapacityUnit.QUARTS);

		}
	    } else if ((targTypePos >= METRIC_WET_CAPACITY_START && (targTypePos <= METRIC_WET_CAPACITY_END))) {

		if ((initTypePos >= ENGLISH_WET_CAPACITY_START) && (initTypePos <= ENGLISH_WET_CAPACITY_END)) {

		    double liters = englishWetCapacityUnits[initTypePos]
			    .toLiters(initValue);
		    result = metricUnits[targTypePos - METRIC_WET_CAPACITY_START].convert(liters,
			    MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_WET_CAPACITY_START && (initTypePos <= METRIC_WET_CAPACITY_END))) {

		    result = metricUnits[targTypePos - METRIC_WET_CAPACITY_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_WET_CAPACITY_START]);

		}
	    }
	    break;
	}
	case 5: // Mass
	{
	    if ((targTypePos >= ENGLISH_MASS_START) && (targTypePos <= ENGLISH_MASS_END)) {
		
		if ((initTypePos >= ENGLISH_MASS_START) && (initTypePos <= ENGLISH_MASS_END)) {

		    result = englishMassUnits[targTypePos].convert(initValue,
			    englishMassUnits[initTypePos]);

		} else if ((initTypePos >= METRIC_MASS_START && (initTypePos <= METRIC_MASS_END))) {

		    double ounces = metricUnits[initTypePos - METRIC_MASS_START]
			    .toEnglishOunces(initValue);
		    result = englishMassUnits[targTypePos].convert(ounces,
			     EnglishMassUnit.OUNCES);

		}
	    } else if ((targTypePos >= METRIC_MASS_START && (targTypePos <= METRIC_MASS_END))) {
		
		if ((initTypePos >= ENGLISH_MASS_START) && (initTypePos <= ENGLISH_MASS_END)) {

		    double grams = englishMassUnits[initTypePos]
			    .toGrams(initValue);
		    result = metricUnits[targTypePos - METRIC_MASS_START].convert(grams,
			     MetricUnit.BASE);

		} else if ((initTypePos >= METRIC_MASS_START && (initTypePos <= METRIC_MASS_END))) {

		    result = metricUnits[targTypePos - METRIC_MASS_START].convert(initValue,
			    metricUnits[initTypePos - METRIC_MASS_START]);
		}
	    }
	    break;
	}
	case 6: // Temperature
	{
	    result = temperatureUnits[targTypePos].convert(initValue,
		    temperatureUnits[initTypePos]);
	    break;
	}
	default:
	    break;
	}
	return result;
    }
}
